package cn.jdemo.base.priorityqueue;

import cn.jdemo.base.Node;

import java.util.PriorityQueue;
import java.util.Queue;
import java.util.concurrent.PriorityBlockingQueue;

/**
 * @see cn.willbj.brief.queue 参考
 *
 * <p> 队列
 * @see Queue
 * @see Queue#offer(Object) 添加
 * @see Queue#add(Object) 添加-容量满异常
 * @see Queue#peek() 检索
 * @see Queue#element() 检索-容量空异常
 * @see Queue#poll() 检索并删除
 * @see Queue#remove() 检索并删除-容量空异常
 *
 * <p> 优先级队列
 * @see java.util.PriorityQueue 底层数组 + 比较器
 * @see java.util.concurrent.PriorityBlockingQueue
 *
 */
public class App {
    public static void main(String[] args) throws InterruptedException {
        tes01();
        testBase();
        testBase02();
        tes03();
    }

    /**
     * 默认小根堆
     * 1
     * 2
     * 3
     */
    public static void tes01() {
        PriorityQueue<Integer> queue = new PriorityQueue<>();
        queue.offer(1);
        queue.offer(3);
        queue.offer(2);

        System.out.println(queue.poll());
        System.out.println(queue.poll());
        System.out.println(queue.poll());
    }

    /**
     * 小根堆
     */
    public static void testBase() {

        PriorityQueue<Node> priorityQueue = new PriorityQueue<Node>((t1,t2)->{
            return t1.getNum() - t2.getNum();
        });
        priorityQueue.offer(Node.builder().num(2).build());
        priorityQueue.offer(Node.builder().num(1).build());
        System.out.println(priorityQueue.poll());// Node(num=1, name=null)
        System.out.println(priorityQueue.poll());// Node(num=2, name=null)
    }

    /**
     * 大根堆
     */
    public static void testBase02() {
        Queue<Node> priorityQueue = new PriorityQueue<Node>((t1,t2)->{
            return t2.getNum() - t1.getNum();
        });
        priorityQueue.offer(Node.builder().num(2).build());
        priorityQueue.offer(Node.builder().num(1).build());
        System.out.println(priorityQueue.poll());// Node(num=2, name=null)
        System.out.println(priorityQueue.poll());// Node(num=1, name=null)
    }

    public static void tes03() throws InterruptedException {
        PriorityBlockingQueue<Node> priorityBlockingQueue = new PriorityBlockingQueue<Node>(16,(t1,t2)->{
            return t2.getNum() - t1.getNum();
        });

        priorityBlockingQueue.offer(Node.builder().num(2).build());
        priorityBlockingQueue.offer(Node.builder().num(1).build());
        System.out.println(priorityBlockingQueue.take());// Node(num=2, name=null)
        System.out.println(priorityBlockingQueue.take());// Node(num=1, name=null)
    }
}
